package pl.edu.agh.agents.gui.actions;

import java.awt.event.ActionEvent;

import javax.swing.AbstractAction;

import pl.edu.agh.agents.agent.Agent;
import pl.edu.agh.agents.agent.ControlledAgent;
import pl.edu.agh.agents.agent.SystemManager;
import pl.edu.agh.agents.gui.GUI;
import pl.edu.agh.agents.gui.GraphUtils;
import pl.edu.agh.agents.planner.CentralPlanner;
import pl.edu.agh.agents.state.State;
import pl.edu.agh.agents.state.StateSpace;

import com.mxgraph.model.mxCell;
import com.mxgraph.model.mxIGraphModel;
import com.mxgraph.view.mxGraph;

public class RemoveAction extends AbstractAction {
	private static final long serialVersionUID = 6121267254710416663L;

	private GUI gui;
	private GraphUtils graphUtils = GraphUtils.getInstance();

	public RemoveAction(String name, GUI gui) {
		super(name);

		this.gui = gui;
	}

	private void removeCell(mxGraph graph, mxIGraphModel graphModel) {
		graphModel.remove(graph.getSelectionCell());

		gui.setRemoveButtonEnabled(false);
	}

	@Override
	public void actionPerformed(ActionEvent arg0) {
		mxGraph graph = gui.getGraph();
		mxIGraphModel graphModel = graph.getModel();
		mxCell cell = (mxCell)graph.getSelectionCell();
		State state = gui.getCellsStates().get(cell);

		if (cell == null) {
			return;
		}

		graphModel.beginUpdate();

		if (state != null) {

			// remove agent
			Agent agent = state.getAgent();
			
			StateSpace.getInstance().removeGoalState(agent);
			SystemManager.getInstance().removeAgent(agent);

			if (agent instanceof ControlledAgent) {
				CentralPlanner.getInstance().removeAgent(agent);
			}
			state.setAgent(null);

			// remove state only if it was empty
			if (agent == null) {
				for (Agent a : SystemManager.getInstance().getAgents()) {
					if (state == a.getGoalState()) {
						gui.showErrorMsg("Nie mozna usunac stanu (jest stanem docelowym agenta " + a.getID() + ")");
					
						graphModel.endUpdate();
						return;
					}
				}

				for (int i = cell.getEdgeCount()-1; i >= 0; i--) {
					graphModel.remove(cell.getEdgeAt(i));
				}

				StateSpace.getInstance().removeState(state);

				removeCell(graph, graphModel);
			}
		}
		else if (cell.isEdge()) {
			mxCell srcCell = (mxCell) cell.getSource();
			mxCell destCell = (mxCell) cell.getTarget();
			State src = gui.getCellsStates().get(srcCell);
			State dest = gui.getCellsStates().get(destCell);
			src.removeNeighbor(dest);

			removeCell(graph, graphModel);
		}

		gui.setRemoveButtonEnabled(false);
		graphModel.endUpdate();

		graphUtils.colorStates(gui);
	}
}